package com.mark.web.bill.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.mark.common.Constant;
import com.mark.common.CurrentUser;
import com.mark.common.ServerResponse;
import com.mark.common.utils.BigDecimalUtil;
import com.mark.common.utils.TrendChartUtil;
import com.mark.web.bill.entity.dto.GoodsDetail;
import com.mark.web.bill.entity.po.Account;
import com.mark.web.bill.entity.po.Goods;
import com.mark.web.bill.entity.vo.AccountVo;
import com.mark.web.bill.enums.AccountEnum;
import com.mark.web.bill.mapper.AccountMapper;
import com.mark.web.bill.mapper.GoodsMapper;
import com.mark.web.bill.service.IAccountService;
import com.mark.web.common.entity.vo.echarts.LineChartVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

@Service
public class AccountServiceImpl implements IAccountService {
    private static final int NOT_GOODS_ID = 0;
    private final AccountMapper accountMapper;
    private final GoodsMapper goodsMapper;

    @Autowired
    public AccountServiceImpl(AccountMapper accountMapper, GoodsMapper goodsMapper) {
        this.accountMapper = accountMapper;
        this.goodsMapper = goodsMapper;
    }


    //region 添加一条个人账单信息
    @Override
    public ServerResponse<String> add(Account account) {
        //通过商品ID获取商品信息
        Goods goods = goodsMapper.selectByPrimaryKey(account.getFkGoodsId());
        if(goods == null){
            return ServerResponse.createByErrorMessage("账单中的加工零件不存在！");
        }
        if(account.getEnableStatus() == null){
            account.setEnableStatus(AccountEnum.UN_PAYMENT.getState());
        }

        //如果账单的创建时间为空，则默认为今天
        if(account.getCreateTime() == null){
            account.setCreateTime(new Date());
        }else{
            account.setCreateTime(getDetailDate(account.getCreateTime()));
        }
        //计算总价
        BigDecimal price = goods.getPrice();
        Integer quantity = account.getQuantity();
        BigDecimal total = BigDecimalUtil.mul(price.doubleValue(), quantity.doubleValue());
        account.setTotalPrice(total);
        int effectNum = accountMapper.insert(account);
        if(effectNum != Constant.SUCCESS){
            ServerResponse.createByErrorMessage("保存信息失败！");
        }
        return ServerResponse.createBySuccessMessage("添加账单记录成功！");
    }
    //endregion

    //region 查找时间范围内的账单信息列表
    @Override
    public ServerResponse<PageInfo<AccountVo>> getAccountListBySearchTime(Long start, Long end, int pageNum, int pageSize, int currentUserId) {
        PageHelper.startPage(pageNum, pageSize);
        Date startDate = new Date(start);
        Date endDate = new Date(end);
        List<Account> accountList = accountMapper.selectAccountsBySearchTime(startDate,endDate,currentUserId);
        List<AccountVo> accountVoList = Lists.newArrayList();
        for(Account account : accountList){
            GoodsDetail goodsDetail = new GoodsDetail();
            if(account.getFkGoodsId() == NOT_GOODS_ID){
                goodsDetail.setCategoryName("无");
                goodsDetail.setGoodsName("无");
                goodsDetail.setPrice(account.getPrice());
            }else{
                goodsDetail = goodsMapper.searchGoodsDetail(account.getFkGoodsId());
            }
            AccountVo accountVo = new AccountVo(account, goodsDetail);
            accountVoList.add(accountVo);
        }
        PageInfo<AccountVo> result = new PageInfo<>(accountVoList);
        result.setTotal(new PageInfo<>(accountList).getTotal());
        return ServerResponse.createBySuccess(result);
    }
    //endregion

    //region 查找搜索时间范围内的账单统计信息（总额，已经结算总额，未结算总额，总加工零件数量）
    @Override
    public ServerResponse<Map<String, Object>> getStatisticalInfo(Long start, Long end, int currentUserId) {
        Date startDate = new Date(start);
        Date endDate = new Date(end);
        BigDecimal totalPrice = accountMapper.getTotalPrice(startDate, endDate, null, currentUserId);
        BigDecimal unPayTotalPrice = accountMapper.getTotalPrice(startDate, endDate, AccountEnum.UN_PAYMENT.getState(), currentUserId);
        BigDecimal payTotalPrice = accountMapper.getTotalPrice(startDate, endDate, AccountEnum.PAYMENT_ED.getState(), currentUserId);
        Integer totalQuantity = accountMapper.getTotalQuantity(startDate, endDate, currentUserId);

        Map<String, Object> resultMap = Maps.newHashMap();
        //总额
        resultMap.put("totalPrice",totalPrice == null ? 0.00 : totalPrice);
        //未支付总额
        resultMap.put("unPayPrice",unPayTotalPrice == null ? 0.00 : unPayTotalPrice);
        //已支付总额
        resultMap.put("payedPrice",payTotalPrice == null ? 0.00 : payTotalPrice);
        //总加工零件个数
        resultMap.put("totalQuantity",totalQuantity == null ? 0.00 : BigDecimalUtil.formatBigDecimal(new BigDecimal(totalQuantity)));
        return ServerResponse.createBySuccess(resultMap);
    }
    //endregion

    //region 趋势图
    @Override
    public ServerResponse<LineChartVo> getLineData(Long startTime, Long endTime, int currentUserId, Boolean totalPriceData) {

        Date startDate = new Date(startTime);
        Date endDate = new Date(endTime);
        List<Map<String,Object>> lineDateList ;
        if(totalPriceData){
            //计算总价的趋势图
            lineDateList = accountMapper.selectAccountLineDate(startDate,endDate,currentUserId);
        }else {
            //计算零件总价数的趋势图
            lineDateList = accountMapper.selectAccountLineQuantityDate(startDate,endDate,currentUserId);
        }

        List<String> xAxisDataList = TrendChartUtil.getDateList();
        //LinkedHashSet保证有序
        LinkedHashSet<String> legendSet = Sets.newLinkedHashSet();
        List<List<Double>> seriesData = TrendChartUtil.getSeriesDate(lineDateList, TrendChartUtil.getDateList(startDate, endDate), legendSet);

        LineChartVo lineChartVo = new LineChartVo();
        lineChartVo.setLegendData(new ArrayList<>(legendSet));
        lineChartVo.setXAxisData(xAxisDataList);
        lineChartVo.setSeriesData(seriesData);
        return ServerResponse.createBySuccess(lineChartVo);
    }
    //endregion

    //region 无需选择商品的方式添加账单
    @Override
    public ServerResponse<String> addNotGoods(Account account) {
        account.setFkGoodsId(NOT_GOODS_ID);
        //如果账单的创建时间为空，则默认为今天
        if(account.getCreateTime() == null){
            account.setCreateTime(new Date());
        }else{
            account.setCreateTime(getDetailDate(account.getCreateTime()));
        }
        //计算总价
        BigDecimal price = account.getPrice();
        Integer quantity = account.getQuantity();
        BigDecimal total = BigDecimalUtil.mul(price.doubleValue(), quantity.doubleValue());
        account.setTotalPrice(total);
        int effectNum = accountMapper.insert(account);
        if(effectNum != Constant.SUCCESS){
            ServerResponse.createByErrorMessage("保存信息失败！");
        }
        return ServerResponse.createBySuccessMessage("添加账单记录成功！");
    }
    //endregion

    //region 删除操作
    @Override
    public ServerResponse<String> delete(int currentUserId, Integer id) {
        int delete = accountMapper.deleteByPrimaryKeyAndUserId(id, currentUserId);
        if(delete != Constant.SUCCESS){
            return ServerResponse.createByErrorMessage("删除账单记录失败！");
        }
        return ServerResponse.createBySuccessMessage("删除账单记录成功！");
    }
    //endregion

    //region 编辑账单
    @Override
    public ServerResponse<String> editNotGoods(Account account) {
        if(accountMapper.selectByPrimaryKey(account.getId()) == null){
            return ServerResponse.createByErrorMessage("原始的账单记录不存在！");
        }
        //计算总价
        BigDecimal price = account.getPrice();
        Integer quantity = account.getQuantity();
        BigDecimal total = BigDecimalUtil.mul(price.doubleValue(), quantity.doubleValue());
        account.setTotalPrice(total);
        int update = accountMapper.updateByPrimaryKeySelective(account);
        if (update != Constant.SUCCESS){
            return ServerResponse.createByErrorMessage("更新账单记录失败！");
        }
        return ServerResponse.createBySuccessMessage("更新账单成功！");
    }
    //endregion

    @Override
    public ServerResponse<String> batchUpdateStatus(String idStr, Long paymentTime) {
        String[] ids = idStr.split(",");
        List<Integer> idList = Lists.newArrayList();
        for (String id : ids) {
            idList.add(Integer.parseInt(id));
        }
        Date paymentDate = new Date(paymentTime);
        int currentUserId = CurrentUser.getCurrentUserId();
        int effectNum = accountMapper.batchUpdateStatusByIds(idList, currentUserId, AccountEnum.PAYMENT_ED.getState(),paymentDate);
        if(effectNum != idList.size()){
            return ServerResponse.createByErrorMessage("更新账单状态失败！");
        }
        return ServerResponse.createBySuccessMessage("更新账单信息成功！");
    }

    @Override
    public ServerResponse<String> batchUpdateStatus(Long start, Long end, Long paymentTime, int currentUserId) {
        Date startDate = new Date(start);
        Date endDate = new Date(end);
        Date paymentDate = new Date(paymentTime);
        int effectNum = accountMapper.batchUpdateStatusByDateRange(startDate, endDate, currentUserId, AccountEnum.PAYMENT_ED.getState(), paymentDate);
        return ServerResponse.createBySuccessMessage("更新账单信息成功！");
    }

    //region 在原来的时间加上小时、分钟和秒
    private Date getDetailDate(Date originalDate) {
        Calendar originalCalendar = Calendar.getInstance();
        originalCalendar.setTime(originalDate);
        int year = originalCalendar.get(Calendar.YEAR);
        int month = originalCalendar.get(Calendar.MONTH);
        int day = originalCalendar.get(Calendar.DAY_OF_MONTH);

        Date result = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(result);
        calendar.set(Calendar.YEAR,year);
        calendar.set(Calendar.MONTH,month);
        calendar.set(Calendar.DAY_OF_MONTH,day);
        return calendar.getTime();
    }
    //endregion

}
